package net.chasing.androidbaseconfig.util.album;

import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;

import net.chasing.androidbaseconfig.util.FileUtils;
import net.chasing.androidbaseconfig.util.thread.ComparableRunnable;
import net.chasing.androidbaseconfig.util.thread.ThreadPoolUtils;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * 注意：
 * load必须运行在主线程
 * 数据回调是在子线程
 */
public class MediaLoader implements LoaderManager.LoaderCallbacks<Cursor> {
    private final String[] IMAGE_PROJECTION = {
            MediaStore.MediaColumns.DATA,
            MediaStore.MediaColumns.DISPLAY_NAME,
            MediaStore.MediaColumns.DATE_ADDED,
            MediaStore.MediaColumns.MIME_TYPE,
            MediaStore.MediaColumns.SIZE,
            MediaStore.MediaColumns.DURATION,
            MediaStore.MediaColumns._ID
    };

    private final String[] selectionArgsImage = new String[]{String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE)};
    private final String[] selectionArgsVideo = new String[]{String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO)};
    private final String[] selectionArgsAudio = new String[]{String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_AUDIO)};
    private final String[] selectionAllArgs = new String[]{String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE),
            String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO)};

    // folder result data set
    private boolean mLoadFinished; //是否已经加载完毕 该标识为了避免 onResume时再次调用
    private boolean mHasFolderGenerated; //文件夹是否已遍历 生成过
    private ArrayList<FolderBean> mResultFolder; //文件夹列表

    private final WeakReference<FragmentActivity> mActivity;
    private IMediaLoaderCallback mCallback;
    private boolean mIsShowGif = true;
    private boolean mIsShowVideo = false;
    private boolean mIsOnlyVideo = false;
    private boolean mIsOnlyAudio = false;

    public MediaLoader(FragmentActivity activity, IMediaLoaderCallback callback) {
        mActivity = new WeakReference<>(activity);
        mCallback = callback;
    }

    public void setShowGif(boolean showGif) {
        mIsShowGif = showGif;
    }

    public void setShowVideo(boolean showVideo) {
        mIsShowVideo = showVideo;
    }

    public void setOnlyVideo(boolean onlyVideo) {
        mIsOnlyVideo = onlyVideo;
    }

    public void setOnlyAudio(boolean onlyAudio) {
        mIsOnlyAudio = onlyAudio;
    }

    public void load() {
        if (mActivity.get() != null)
            LoaderManager.getInstance(mActivity.get()).initLoader(0, null, MediaLoader.this);
    }

    @NonNull
    @Override
    public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
        CursorLoader cursorLoader;
        Uri contentUri = MediaStore.Files.getContentUri("external");
        String selection;
        String[] selectionArgs;

        if (mIsOnlyAudio) {
            selection = "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)";
            selectionArgs = selectionArgsAudio;
        } else if (mIsOnlyVideo) {
            selection = "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)";
            selectionArgs = selectionArgsVideo;
        } else if (!mIsShowVideo) {
            selection = "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)";
            selectionArgs = selectionArgsImage;
        } else {
            selection = "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                    + " OR " + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)";
            selectionArgs = selectionAllArgs;
        }

        cursorLoader = new CursorLoader(mActivity.get(),
                contentUri,
                IMAGE_PROJECTION,
                selection,
                selectionArgs,
                IMAGE_PROJECTION[2] + " DESC");
        mLoadFinished = false;
        mHasFolderGenerated = false;
        return cursorLoader;
    }

    @Override
    public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
        if (!mLoadFinished && data != null) {
            ThreadPoolUtils.getInstance().execute(new ComparableRunnable() {
                @Override
                public void run() {
                    mLoadFinished = true;
                    if (mResultFolder == null)
                        mResultFolder = new ArrayList<>();
                    else
                        mResultFolder.clear();

                    if (data.getCount() > 0) {
                        List<MediaBean> allList = new ArrayList<>();
                        List<MediaBean> allVideoList = new ArrayList<>();
                        data.moveToFirst();
                        String path, name, mineType;
                        long dateTime, duration, id;
                        MediaBean mediaBean;
                        File folderFile;
                        FolderBean folder, f;
                        List<MediaBean> mediaBeanList;
                        Uri contentUri = MediaStore.Files.getContentUri("external");
                        do {
                            path = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));
                            name = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));
                            mineType = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[3]));
                            dateTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));
                            id = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[6]));

                            if (TextUtils.isEmpty(mineType) || FileUtils.getFileLength(path) == 0) {
                                continue;
                            }
                            //过滤GIF
                            if (!mIsShowGif && (mineType.contains(MineType.GIF) || path.endsWith(MineType.GIF))) {
                                continue;
                            }

                            Uri uri = ContentUris.withAppendedId(contentUri, id);

                            //创建单个实体类
                            if (mineType.contains(MineType.VIDEO) || mineType.contains(MineType.AUDIO)) {
                                duration = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[5]));
                                mediaBean = new MediaBean(path, name, mineType, dateTime, duration);
                                allVideoList.add(mediaBean);
                            } else {
                                mediaBean = new MediaBean(path, name, mineType, dateTime);
                            }
                            mediaBean.uri = uri;
                            allList.add(mediaBean);

                            //没有创建文件夹，先创建文件夹，已创建则直接加入
                            if (!mHasFolderGenerated) {
                                // get all folder data
                                folderFile = new File(path).getParentFile();
                                if (folderFile != null) {
//                                if (folderFile != null && folderFile.exists()) {
                                    String fp = folderFile.getAbsolutePath();
                                    f = getFolderByPath(fp);
                                    if (f == null) {
                                        folder = new FolderBean();
                                        folder.name = folderFile.getName();
                                        folder.path = fp;
                                        folder.cover = mediaBean;
                                        mediaBeanList = new ArrayList<>();
                                        mediaBeanList.add(mediaBean);
                                        folder.mediaList = mediaBeanList;
                                        mResultFolder.add(folder);
                                    } else {
                                        f.mediaList.add(mediaBean);
                                    }
                                }
                            }

                        } while (!data.isClosed() && data.moveToNext());

                        if (!data.isClosed()) { // 关闭了界面，Cursor就会被关闭，则进行判断关闭了的话就不进行后续操作了
                            //混合类型，添加所有视频集合，如果有的话
                            if (!mIsOnlyVideo && mIsShowVideo && !allVideoList.isEmpty()) {
                                FolderBean allVideoFolder = new FolderBean();
                                allVideoFolder.name = "所有视频";
                                allVideoFolder.path = "/sdcard";
                                allVideoFolder.cover = allVideoList.get(0);
                                allVideoFolder.mediaList = allVideoList;
                                mResultFolder.add(0, allVideoFolder);
                            }

                            //添加所有图片(包括视频)集合
                            if (!allList.isEmpty()) {
                                //构造所有图片的集合
                                FolderBean allImagesFolder = new FolderBean();

                                if (mIsOnlyAudio) {
                                    allImagesFolder.name = "所有音频";
                                } else if (mIsOnlyVideo) {
                                    allImagesFolder.name = "所有视频";
                                } else if (mIsShowVideo) {
                                    allImagesFolder.name = "图片和视频";
                                } else {
                                    allImagesFolder.name = "所有图片";
                                }
                                allImagesFolder.path = "/sdcard";
                                allImagesFolder.cover = allList.get(0);
                                allImagesFolder.mediaList = allList;
                                mResultFolder.add(0, allImagesFolder);
                            }

                            mHasFolderGenerated = true;
                            if (mCallback != null) {
                                mCallback.onLoadFinish(mResultFolder);
                                mResultFolder = null;
                            }
                        }
                    } else {
                        if (mCallback != null) {
                            mCallback.onLoadFinish(mResultFolder);
                            mResultFolder = null;
                        }
                    }

                    ThreadPoolUtils.getInstance().executeOnMainThread(() -> {
                        // 销毁MediaLoader，不销毁，每次返回界面都会执行一次查询
                        if (mActivity.get() != null)
                            LoaderManager.getInstance(mActivity.get()).destroyLoader(0);
                        mActivity.clear();
                        mCallback = null;
                    });
                }
            });
        } else {
            if (mCallback != null) {
                mCallback.onLoadFinish(mResultFolder);
                mResultFolder = null;
            }
            ThreadPoolUtils.getInstance().executeOnMainThread(() -> {
                // 销毁MediaLoader，不销毁，每次返回界面都会执行一次查询
                if (mActivity.get() != null)
                    LoaderManager.getInstance(mActivity.get()).destroyLoader(0);
                mActivity.clear();
                mCallback = null;
            });
        }
    }

    @Override
    public void onLoaderReset(@NonNull Loader<Cursor> loader) {

    }

    private FolderBean getFolderByPath(String path) {
        if (mResultFolder != null)
            for (FolderBean folder : mResultFolder) {
                if (TextUtils.equals(folder.path, path)) {
                    return folder;
                }
            }
        return null;
    }
}
